home *** CD-ROM | disk | FTP | other *** search
/ PC World Komputer 2010 April / PCWorld0410.iso / hity wydania / Blender 2.49b / blender-2.49b-windows.exe / $_4_ / .blender / scripts / bpymodules / BPyImage.py < prev    next >
Text File  |  2009-08-31  |  11KB  |  319 lines

  1. # --------------------------------------------------------------------------
  2. # BPyImage.py version 0.15
  3. # --------------------------------------------------------------------------
  4. # helper functions to be used by other scripts
  5. # --------------------------------------------------------------------------
  6. # ***** BEGIN GPL LICENSE BLOCK *****
  7. #
  8. # This program is free software; you can redistribute it and/or
  9. # modify it under the terms of the GNU General Public License
  10. # as published by the Free Software Foundation; either version 2
  11. # of the License, or (at your option) any later version.
  12. #
  13. # This program is distributed in the hope that it will be useful,
  14. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  16. # GNU General Public License for more details.
  17. #
  18. # You should have received a copy of the GNU General Public License
  19. # along with this program; if not, write to the Free Software Foundation,
  20. # Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21. #
  22. # ***** END GPL LICENCE BLOCK *****
  23. # --------------------------------------------------------------------------
  24.  
  25. #===========================================================================#
  26. # Comprehensive image loader, will search and find the image                #
  27. # Will return a blender image or a new image if the image is missing        #
  28. #===========================================================================#
  29. import bpy
  30. from Blender import sys
  31. try:
  32.     import os
  33. except:
  34.     os=None
  35.  
  36. #==============================================#
  37. # Return directory, where the file is          #
  38. #==============================================#
  39. def stripFile(path):
  40.     lastSlash = max(path.rfind('\\'), path.rfind('/'))
  41.     if lastSlash != -1:
  42.         path = path[:lastSlash]
  43.         newpath= '%s%s' % (path, sys.sep)
  44.     else:
  45.         newpath= path
  46.     return newpath
  47.  
  48. #==============================================#
  49. # Strips the slashes from the back of a string #
  50. #==============================================#
  51. def stripPath(path):
  52.     return path.split('/')[-1].split('\\')[-1]
  53.  
  54. #====================================================#
  55. # Strips the prefix off the name before writing      #
  56. #====================================================#
  57. def stripExt(name): # name is a string
  58.     index = name.rfind('.')
  59.     if index != -1:
  60.         return name[ : index ]
  61.     else:
  62.         return name
  63.  
  64. def getExt(name):
  65.     index = name.rfind('.')
  66.     if index != -1:
  67.         return name[index+1:]
  68.     return name
  69.  
  70. #====================================================#
  71. # Adds a slash to the end of a path if its not there #
  72. #====================================================#
  73. def addSlash(path):
  74.     if not path:
  75.         return ''
  76.     
  77.     elif path.endswith('\\') or path.endswith('/'):
  78.         return path
  79.     return path + sys.sep
  80.  
  81.  
  82. def comprehensiveImageLoad(imagePath, filePath, PLACE_HOLDER= True, RECURSIVE=True, VERBOSE=False, CONVERT_CALLBACK=None):
  83.     '''
  84.     imagePath: The image filename
  85.         If a path precedes it, this will be searched as well.
  86.         
  87.     filePath: is the directory where the image may be located - any file at teh end will be ignored.
  88.     
  89.     PLACE_HOLDER: if True a new place holder image will be created.
  90.         this is usefull so later you can relink the image to its original data.
  91.     
  92.     VERBOSE: If True debug info will be printed.
  93.     
  94.     RECURSIVE: If True, directories will be recursivly searched.
  95.         Be carefull with this if you have files in your root directory because it may take a long time.
  96.     
  97.     CASE_INSENSITIVE: for non win32 systems, find the correct case for the file.
  98.     
  99.     CONVERT_CALLBACK: a function that takes an existing path and returns a new one.
  100.         Use this when loading image formats blender may not support, the CONVERT_CALLBACK
  101.         can take the path for a GIF (for example), convert it to a PNG and return the PNG's path.
  102.         For formats blender can read, simply return the path that is given.
  103.     '''
  104.     
  105.     # VERBOSE = True
  106.     
  107.     if VERBOSE: print 'img:', imagePath, 'file:', filePath
  108.     
  109.     if os == None and CASE_INSENSITIVE:
  110.         CASE_INSENSITIVE = True
  111.     
  112.     # When we have the file load it with this. try/except niceness.
  113.     def imageLoad(path):
  114.         #if path.endswith('\\') or path.endswith('/'):
  115.         #    raise 'INVALID PATH'
  116.         
  117.         if CONVERT_CALLBACK:
  118.             path = CONVERT_CALLBACK(path)
  119.         
  120.         try:
  121.             img = bpy.data.images.new(filename=path)
  122.             if VERBOSE: print '\t\tImage loaded "%s"' % path
  123.             return img
  124.         except:
  125.             if VERBOSE:
  126.                 if sys.exists(path): print '\t\tImage failed loading "%s", mabe its not a format blender can read.' % (path)
  127.                 else: print '\t\tImage not found, making a place holder "%s"' % (path)
  128.             if PLACE_HOLDER:
  129.                 img= bpy.data.images.new(stripPath(path),4,4)
  130.                 img.filename= path
  131.                 return img #blank image
  132.             else:
  133.                 return None
  134.             
  135.     # Image formats blender can read
  136.     IMAGE_EXT = ['jpg', 'jpeg', 'png', 'tga', 'bmp', 'rgb', 'sgi', 'bw', 'iff', 'lbm', # Blender Internal
  137.     'gif', 'psd', 'tif', 'tiff', 'pct', 'pict', 'pntg', 'qtif'] # Quacktime, worth a try.
  138.     
  139.     imageFileName =  stripPath(imagePath) # image path only
  140.     imageFileName_lower =  imageFileName.lower() # image path only
  141.     
  142.     if VERBOSE: print '\tSearchingExisting Images for "%s"' % imagePath
  143.     for i in bpy.data.images:
  144.         if stripPath(i.filename.lower()) == imageFileName_lower:
  145.             if VERBOSE: print '\t\tUsing existing image.'
  146.             return i
  147.     
  148.     
  149.     if VERBOSE: print '\tAttempting to load "%s"' % imagePath
  150.     if sys.exists(imagePath):
  151.         if VERBOSE: print '\t\tFile found where expected "%s".' % imagePath
  152.         return imageLoad(imagePath)
  153.     
  154.     
  155.     
  156.     imageFileName_noext = stripExt(imageFileName) # With no extension.
  157.     imageFileName_noext_lower = stripExt(imageFileName_lower) # With no extension.
  158.     imageFilePath = stripFile(imagePath)
  159.     
  160.     # Remove relative path from image path
  161.     if imageFilePath.startswith('./') or imageFilePath.startswith('.\\'):
  162.         imageFilePath = imageFilePath[2:]
  163.     
  164.     
  165.     # Attempt to load from obj path.
  166.     tmpPath = stripFile(filePath) + stripPath(imageFileName)
  167.     if sys.exists(tmpPath):
  168.         if VERBOSE: print '\t\tFile found in path (1)"%s".' % tmpPath
  169.         return imageLoad(tmpPath)
  170.     
  171.     
  172.     # os needed if we go any further.
  173.     if not os:
  174.         if VERBOSE: print '\t\tCreating a placeholder with a face path: "%s".' % imagePath
  175.         return imageLoad(imagePath) # Will jus treturn a placeholder.
  176.     
  177.     
  178.     # We have os.
  179.     # GATHER PATHS.
  180.     paths = {} # Store possible paths we may use, dict for no doubles.
  181.     tmpPath = addSlash(sys.expandpath('//')) # Blenders path
  182.     if sys.exists(tmpPath):
  183.         if VERBOSE: print '\t\tSearching in %s' % tmpPath
  184.         paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading 
  185.         paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
  186.         paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
  187.     else:
  188.         if VERBOSE: print '\tNo Path: "%s"' % tmpPath
  189.     
  190.     tmpPath = imageFilePath
  191.     if sys.exists(tmpPath):
  192.         if VERBOSE: print '\t\tSearching in %s' % tmpPath
  193.         paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading 
  194.         paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
  195.         paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
  196.     else:
  197.         if VERBOSE: print '\tNo Path: "%s"' % tmpPath
  198.  
  199.     tmpPath = stripFile(filePath)
  200.     if sys.exists(tmpPath):
  201.         if VERBOSE: print '\t\tSearching in %s' % tmpPath
  202.         paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading 
  203.         paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
  204.         paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
  205.     else:
  206.         if VERBOSE: print '\tNo Path: "%s"' % tmpPath
  207.  
  208.     tmpPath = addSlash(bpy.config.textureDir)
  209.     if tmpPath and sys.exists(tmpPath):
  210.         if VERBOSE: print '\t\tSearching in %s' % tmpPath
  211.         paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading 
  212.         paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
  213.         paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
  214.     else:
  215.         if VERBOSE: print '\tNo Path: "%s"' % tmpPath
  216.     
  217.     # Add path if relative image patrh was given.
  218.     tmp_paths= paths.keys()
  219.     for k in tmp_paths:
  220.         tmpPath = k + imageFilePath
  221.         if sys.exists(tmpPath):
  222.             paths[tmpPath] = [os.listdir(tmpPath)] # Orig name for loading 
  223.             paths[tmpPath].append([f.lower() for f in paths[tmpPath][0]]) # Lower case list.
  224.             paths[tmpPath].append([stripExt(f) for f in paths[tmpPath][1]]) # Lower case no ext
  225.         else:
  226.             if VERBOSE: print '\tNo Path: "%s"' % tmpPath
  227.     # DONE
  228.     # 
  229.     for path, files in paths.iteritems():
  230.         if sys.exists(path + imageFileName):
  231.             if VERBOSE: print '\tFound image at path: "%s" file" "%s"' % (path, imageFileName)
  232.             return imageLoad(path + imageFileName)
  233.         
  234.         # If the files not there then well do a case insensitive seek.
  235.         filesOrigCase = files[0]
  236.         filesLower = files[1]
  237.         filesLowerNoExt = files[2]
  238.         
  239.         # We are going to try in index the file directly, if its not there just keep on
  240.         
  241.         index = None
  242.         try:
  243.             # Is it just a case mismatch?
  244.             index = filesLower.index(imageFileName_lower)
  245.         except:
  246.             try:
  247.                 # Have the extensions changed?
  248.                 index = filesLowerNoExt.index(imageFileName_noext_lower)
  249.                 
  250.                 ext = getExt( filesLower[index] ) # Get the extension of the file that matches all but ext.
  251.                 
  252.                 # Check that the ext is useable eg- not a 3ds file :)
  253.                 if ext.lower() not in IMAGE_EXT:
  254.                     index = None
  255.             
  256.             except:
  257.                 index = None
  258.         
  259.         if index != None:
  260.             tmpPath = path + filesOrigCase[index]
  261.             img = imageLoad( tmpPath )
  262.             if img != None:
  263.                 if VERBOSE: print '\t\tImage Found "%s"' % tmpPath
  264.                 return img
  265.     
  266.     if RECURSIVE:
  267.         # IMAGE NOT FOUND IN ANY OF THE DIRS!, DO A RECURSIVE SEARCH.
  268.         if VERBOSE: print '\t\tImage Not Found in any of the dirs, doing a recusrive search'
  269.         for path in paths.iterkeys():
  270.             # Were not going to use files
  271.             if path == '/' or len(path) == 3 and path[1:] == ':\\':
  272.                 continue
  273.             
  274.             # print path , 'ASS'
  275.             
  276.             #------------------
  277.             # finds the file starting at the root.
  278.             #    def findImage(findRoot, imagePath):
  279.             #W---------------
  280.             
  281.             # ROOT, DIRS, FILES
  282.             pathWalk = os.walk(path)
  283.             pathList = [True]
  284.             
  285.             matchList = [] # Store a list of (match, size), choose the biggest.
  286.             while True:
  287.                 try:
  288.                     pathList  = pathWalk.next()
  289.                 except:
  290.                     break
  291.                 
  292.                 for file in pathList[2]:
  293.                     file_lower = file.lower()
  294.                     # FOUND A MATCH
  295.                     if (file_lower == imageFileName_lower) or\
  296.                     (stripExt(file_lower) == imageFileName_noext_lower and getExt(file_lower) in IMAGE_EXT):
  297.                         name = pathList[0] + sys.sep + file
  298.                         size = os.path.getsize(name)
  299.                         if VERBOSE: print '\t\t\tfound:', name 
  300.                         matchList.append( (name, size) )
  301.             
  302.             if matchList:
  303.                 # Sort by file size
  304.                 matchList.sort(lambda A, B: cmp(B[1], A[1]) )
  305.                 
  306.                 if VERBOSE: print '\t\tFound "%s"' % matchList[0][0]
  307.                 
  308.                 # Loop through all we have found
  309.                 img = None
  310.                 for match in matchList:
  311.                     img = imageLoad(match[0]) # 0 - first, 0 - pathname
  312.                     if img != None:
  313.                         break
  314.                 return img
  315.     
  316.     # No go.
  317.     if VERBOSE: print '\t\tImage Not Found after looking everywhere! "%s"' % imagePath
  318.     return imageLoad(imagePath) # Will jus treturn a placeholder.
  319.